import { Render, Circle, Text, PickContrls, Vector2 } from '../two/two.js'
import { Mouse } from './object.js'


class Render_ {
    constructor(width = 400, height = 300) {
        const that = this
        this._callback = null
        this.animation = function(callback) {
            that.ctx.clearRect(0, 0, that.render._width * that.render._pixelRatio, that.render._height * that.render._pixelRatio)
            if (typeof callback == 'function') {
                that._callback = callback
            }
            if (typeof that._callback == 'function') {
                that._callback()
            }
        }
        this.render = new Render()
        this.render.setSize(width, height)
        this.render.setPixelRatio(2)
        // render.setTickLength(1000 / 10)
        this.render.setAnimationLoop(this.animation)
        document.querySelector('body').appendChild(this.render.domElement)
        this.ctx = this.render._context

        this.mouse = new Mouse(this.render.domElement)
        this.mouse.setPixelRatio(2)
    }


    frame(kframe) {
        this.render.setTickLength(1000 / kframe)
    }

    fill(style='rgb(255, 255, 204)') {
        this.ctx.fillStyle = style
        this.ctx.fill()
    }

    stroke(style='rgb(255, 255, 204)', lineWidth=1) {
        this.ctx.lineWidth = lineWidth
        this.ctx.strokeStyle = style
        this.ctx.stroke()
    }

    draw(x, y, points=[], close=true) {
        if (!this.render) {
            console.error("not createCanvas before")
            return
        }
        if (!points || points.length <= 0) {
            console.error("empty points")
            return
        }
        this.ctx.beginPath()
        let vector = Vector2.add(vector2(x, y), points[0])
        this.ctx.moveTo(vector.x, vector.y)
        for (let j = 1, jl = points.length; j < jl; j++) {
            vector = Vector2.add(vector2(x, y), points[j])
            this.ctx.lineTo(vector.x, vector.y)
        }
        if (close) {
            vector = Vector2.add(vector2(x, y), points[0])
            this.ctx.lineTo(vector.x, vector.y)
        }

    }

    curve(vertices=[], callback=fill) {
        this.ctx.beginPath()
        this.ctx.moveTo(vertices[0].x, vertices[0].y)
        for (let i = 1; i < vertices.length - 1; ++i) {
            this.ctx.quadraticCurveTo(vertices[i].x, vertices[i].y, vertices[i + 1].x, vertices[i + 1].y)
        }
        callback()
    }

    circle(x, y, radius=10, segments = 18, thetaStart = 0, thetaLength = Math.PI * 2) {
        let vertices = []
        for (let s = segments; s >= 0; --s) {
            const segment = thetaStart + s / segments * thetaLength;
            // vertex
            const vertex = new Vector2();
            vertex.x = radius * Math.cos(segment);
            vertex.y = radius * Math.sin(segment);

            vertices.push(vertex);
        }
        this.draw(x, y, vertices)
    }

    rect(x, y, width = 1, height = 1, widthSegments = 1, heightSegments = 1) {
        let vertices = []
        const segment_width = width / widthSegments;
        const segment_height = height / heightSegments;

        const width_half = width / 2;
        const height_half = height / 2;

        for (let ix = 0; ix < widthSegments; ix++) {
            const x = ix * segment_width - width_half
            vertices.push(new Vector2(x, height_half))
        }
        for (let iy = 0; iy < heightSegments; iy++) {
            const y = iy * segment_height - height_half;
            vertices.push(new Vector2(width_half, -y))
        }
        for (let ix = 0; ix < widthSegments; ix++) {
            const x = ix * segment_width - width_half
            vertices.push(new Vector2(-x, -height_half))
        }

        for (let iy = 0; iy < heightSegments; iy++) {
            const y = iy * segment_height - height_half;
            vertices.push(new Vector2(-width_half, y))
        }
        this.draw(x, y, vertices)
    }

    line(x1, y1, x2, y2) {
        this.draw(x1, y1, [vector2(0, 0), vector2(x2 - x1, y2 - y1)])
    }
}


function createCanvas(width = 400, height = 300) {
    let render = new Render_(width, height)
    return render
}

function vector2(x = 0, y = 0) {
    return new Vector2(x, y)
}

function vector28Angle(angle) {
    return Vector2.setAngle(angle)
}

export { createCanvas, Render_, vector2, vector28Angle }